package com.crazy.service.sys.impl;

import static org.hibernate.criterion.Projections.property;
import static org.hibernate.criterion.Restrictions.eq;
import static org.hibernate.criterion.Restrictions.isNotNull;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.transaction.Transactional;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.crazy.common.constants.Const;
import com.crazy.dao.sys.PubResourceDao;
import com.crazy.dao.sys.PubUserDao;
import com.crazy.entity.sys.PubUser;
import com.crazy.service.sys.PubUserService;

/**
 * 用户Service实现类
 * 
 * @author Zhang Weiwei
 * @since 2013-9-20下午1:52:41
 */
@Service
@Transactional
public class PubUserServiceImpl extends BaseServiceImpl<PubUser> implements
		PubUserService {
	private static String MSG_KEY = "DigestProcessingFilter.usernameNotFound";
	@Inject
	private MessageSourceAccessor accessor;
	@Inject
	private PubResourceDao resourceDao;
	@Inject
	private PubUserDao dao;

	/**
	 * 按登录用户名查询用户对象
	 */
	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		PubUser user = this.dao.findUniqueResult("userAccount", username);
		if (user == null) {
			String[] args = { username };
			String msg = this.accessor.getMessage(MSG_KEY, args);
			throw new UsernameNotFoundException(msg);
		}
		DetachedCriteria dc = this.resourceDao.getDetachedCriteria();
		dc.createCriteria("pubRoles", "role")
				.createCriteria("pubUsers", "user");
		dc.add(eq("user.userAccount", username));
		dc.add(eq("user.enabled", true));
		dc.add(eq("role.enabled", Const.ENABLE.getStatus()));
		dc.add(eq("this.enabled", Const.ENABLE.getStatus()));
		dc.add(isNotNull("this.authorityName"));
		dc.setProjection(property("this.authorityName"));
		List<String> list = this.resourceDao.findByDetachedCriteria(dc);
		List<GrantedAuthority> gas = new ArrayList<GrantedAuthority>();
		GrantedAuthority ga = null;
		for (String role : list) {
			ga = new SimpleGrantedAuthority(role);
			gas.add(ga);
		}
		user.setAuthorities(gas);
		return user;
	}
}
